package ru.spb.osll.myfit.client.widget;

import java.util.HashMap;

import ru.spb.osll.myfit.common.Include;
import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.PageElement;
import ru.spb.osll.myfit.common.PageElementType;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.DisclosurePanelImages;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * The includeWidget is created based on data from Include. The includeWidget is
 * a DecoratePanel, which contains tableWidgets and other IncludeWidgets.
 * 
 * @author Mariya Gavrilova
 * 
 */
@SuppressWarnings("deprecation")
public class IncludeWidget extends PageElementWidget {

  /**
   * included page
   */
  protected final Page includePage;

  /**
   * included page path
   */
  protected final String includePath;

  /**
   * widget, that content all other widgets on the page.
   */
  protected PageWidget m_contentWidget;

  /**
   * upper panel.
   */
  protected DisclosurePanel m_advancedDisclosure;

  protected final PageElementType m_type;
  
  protected VerticalPanel vpanel = new VerticalPanel();

  private DisclosurePanelImages images = GWT.create(DisclosurePanelImages.class);
  
  private Image icon;
  /**
   * 
   * @param include
   * @param width
   *          - width of widget
   */
  public IncludeWidget(GWTWidgetFactory gwtWidgetFactory, Include include) {
    super(gwtWidgetFactory);
    sinkEvents(Event.ONMOUSEUP | Event.ONDBLCLICK | Event.ONCONTEXTMENU);
    createPopupMenu();
    m_type = include.getType();
    includePage = include.getPage();
    includePath = include.getPath();
    initWidget(createContentWidget());
    setNeedfulStyles();
  }

  /**
   * create widget, which will be added into a panel (DecoratorPanel)
   * 
   * @return Widget - created widget
   */
  protected Widget createContentWidget() {

    m_contentWidget = new PageWidget(m_gwtWidgetFactory);
    m_contentWidget.setPage(includePage);
    String includeTitle = getIncludeName() + ": ";
    m_advancedDisclosure = (DisclosurePanel) m_gwtWidgetFactory
        .createDisclosurePanelWithoutHeader(m_contentWidget);
    
    icon = images.disclosurePanelClosed().createImage();
    HorizontalPanel panel =  new HorizontalPanel();
    icon.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent arg0) {
        boolean isOpen = m_advancedDisclosure.isOpen();
        setOpenPanel(!isOpen);
      }
    });
    
    panel.add(icon);
    panel.add(new Label(includeTitle));
    panel.add(new HTML("<a href=\"" + getIncludeLink() + "\">" + getIncludePath() +"</>"));
    panel.setCellVerticalAlignment(icon, HasVerticalAlignment.ALIGN_MIDDLE);
    panel.setCellHorizontalAlignment(icon, HasHorizontalAlignment.ALIGN_CENTER);
    panel.setCellWidth(icon, "" + icon.getWidth() + "px");
    panel.setSpacing(3);
    vpanel.add(panel);
    vpanel.add(m_advancedDisclosure);
    return vpanel;
  }
  
  
  protected void setNeedfulStyles(){
//	  m_advancedDisclosure.setStyleName(IStyleConstants.INCLUDE_STYLE_NAME);
    vpanel.setStyleName(IStyleConstants.INCLUDE_STYLE_NAME);
  }
  
  protected String getIncludeName() {
    PageElementType type = getType();
    return type.getKey();
  }

  protected String getIncludePath() {
    return includePath;
  }
  
  protected String getIncludeLink() {
    String link = getIncludePath();
    if (link.startsWith(".")) {
      link = link.substring(1);
    }
    return link;
  }

  /**
   * Changes the visible state of this DisclosurePanel. And does it recursively
   * to all sub_includes.
   * 
   * @param isOpen
   *          true to "open" the widget, false to close.
   */
  @Override
  public void setOpen(boolean isOpen) {
    setOpenPanel(isOpen);
    m_contentWidget.setOpen(isOpen);
  }

  private void setOpenPanel(boolean isOpen){
    m_advancedDisclosure.setOpen(isOpen);
    if(isOpen){
      images.disclosurePanelOpen().applyTo(icon);
    }else{
      images.disclosurePanelClosed().applyTo(icon);
    }
  }
  
  public PageElement getPageElement() {
    return new Include(includePath, includePage);
  }

  public PageElementType getType() {
    return m_type;
  }

  public PageWidget getPageWidget() {
    return m_contentWidget;
  }

  public HashMap<String, String> getVariables() {
    return includePage.getParentVariables();
  }

  public void setVariables(HashMap<String, String> map) {
    m_contentWidget.setVariables(map);
  }

  public void updateWidgets(HashMap<String, String> map) {
    if(map != null)
      m_contentWidget.updateWidgets(map);
  }
}
